﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using KBEngine.Export;
using KBEngine.Setting;
using KBEngine.Setting.TypeDef;

namespace KBEngineTool
{
    internal class EntityLoader
    {
        Types _types = new Types();
        public List<BaseType> AllTypes => _types.AllTypes;
        public Dictionary<string, EntitySetting> AllEntitySetting;

        private string _entityDefFolder;
        private string _entitiesXML;
        private string _typesXML;

        public void Read(string entityDefFolder, string entitiesXML, string typesXML)
        {
            _entityDefFolder = entityDefFolder;
            _entitiesXML = entitiesXML;
            _typesXML = typesXML;

            //读取类型定义
            _types = XmlSerializeOpt.XmlDeserializeByFile<Types>(_typesXML);

            //实体定义占位
            AllEntitySetting = new Dictionary<string, EntitySetting>();
            foreach (ClassType entityFlag in Enum.GetValues(typeof(ClassType)))
            {
                string folder = ClassTypeToFolder(entityFlag);
                foreach (FileInfo file in new DirectoryInfo(Path.Combine(_entityDefFolder, folder)).GetFiles("*.def"))
                {
                    string entityName = Path.GetFileNameWithoutExtension(file.Name);
                    AllEntitySetting.Add(entityName, new EntitySetting() { name = entityName, entityType = entityFlag });
                }
            }

            //读取配置
            XmlDocument xmlDoc = new XmlDocument();
            foreach (var item in AllEntitySetting)
            {
                var filePath = Path.Combine(_entityDefFolder, ClassTypeToFolder(item.Value.entityType) + item.Value.name + ".def");
                item.Value.entity = XmlSerializeOpt.XmlDeserializeByFile<Entity>(filePath);
            }

            //读取实体注册清单
            var entitys = XmlSerializeOpt.XmlDeserializeByFile<Entities>(_entitiesXML);
            foreach (var item in entitys.entityInfos)
            {
                if (!AllEntitySetting.TryGetValue(item.entityName, out var entityItem))
                    throw new System.IO.FileNotFoundException(string.Format("Entity '{0}' is not exists.", item.entityName));
                entityItem.register = true;
                entityItem.hasClient = item.hasClient;
            }
        }
        public bool Write(string userTypeFolder = null)
        {
            //写入类型定义
            XmlSerializeOpt.XmlSerializeToFile(_typesXML, _types);

            //写入实体定义
            XmlDocument xmlDoc = new XmlDocument();
            var cmpObj = new EntitySetting();
            foreach (var item in AllEntitySetting)
            {
                var filePath = Path.Combine(_entityDefFolder, ClassTypeToFolder(item.Value.entityType) + item.Value.name + ".def");
                XmlSerializeOpt.XmlSerializeToFile(filePath, item.Value.entity);
            }

            //写入实体注册清单
            Entities entitys = new Entities();
            foreach (var item in AllEntitySetting)
            {
                if (!item.Value.register)
                    continue;
                Entities.Info info = new Entities.Info();
                info.entityName = item.Key;
                info.hasClient = item.Value.hasClient;
                entitys.entityInfos.Add(info);
            }
            XmlSerializeOpt.XmlSerializeToFile(_entitiesXML, entitys);

            if (userTypeFolder == null)
                return true;

            //导出自定义结构类型code
            var export = new UserTypeExport(AllTypes);
            return export.Save(userTypeFolder);
        }
    

        #region UserType

        public IType GetType(string typeStr)
        {
            return _types.GetType(typeStr);
        }
        public string GetTypeStr(IType itype)
        {
            return _types.GetTypeStr(itype);
        }
        private string ClassTypeToFolder(ClassType entityFlag)
        {
            return entityFlag != ClassType.None ? entityFlag.ToString().ToLower() + "/" : string.Empty;
        }
        #endregion
    }
}
